﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ObjectTreeViewerService.cs" company="tvori.info">
//   2012
// </copyright>
// <summary>
//   The object tree viewer service.
// </summary>
// --------------------------------------------------------------------------------------------------------------------



using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;

using Syberia.Client;
using Syberia.Forms;

namespace Syberia.Metacode
{
    /// <summary>
    /// The object tree viewer service.
    /// </summary>
    public class ObjectTreeViewerService
    {
        /// <summary>
        /// The tracked objects.
        /// </summary>
        private static readonly List<object> TrackedObjects = new List<object>();

        /// <summary>
        /// The form.
        /// </summary>
        private ObjectTreeViewerForm form;


        /// <summary>
        /// resets tracked objs
        /// </summary>
        public static void ResetObjects()
        {
            TrackedObjects.Clear();
        }

        /// <summary>
        /// The track object.
        /// </summary>
        /// <param name="o">
        /// The o.
        /// </param>
        public static void TrackObject(object o)
        {
            TrackedObjects.Add(o);
        }

        /// <summary>
        /// The node after select.
        /// </summary>
        /// <param name="args">
        /// The args.
        /// </param>
        public void NodeAfterSelect(TreeViewEventArgs args)
        {
            try
            {
                var eo = args.Node.Tag as ExplorableObject;
                if (eo == null)
                {
                    return;
                }

                this.form.propertyGrid1.SelectedObject = eo.EditableObject;
            }
            catch (Exception e)
            {
                // Logger.Log("Failure:",e);
            }
        }

        /// <summary>
        /// The node before expand.
        /// </summary>
        /// <param name="args">
        /// The args.
        /// </param>
        public void NodeBeforeExpand(TreeViewCancelEventArgs args)
        {
            var o = args.Node.Tag as ExplorableObject;
            if (o == null)
            {
                args.Cancel = true;
            }

            IEnumerable<ExplorableObject> subo = o.SubObjects;
            if (subo == null)
            {
                args.Cancel = true;
            }

            try
            {
                this.form.treeView1.BeginUpdate();
                args.Node.Nodes.Clear();
                foreach (var oo in subo)
                {
                    args.Node.Nodes.Add(oo.Visualize());
                }

                if (args.Node.Nodes.Count == 0)
                {
                    args.Cancel = true;
                }
            }
            catch (Exception oe)
            {
                // Logger.Log("Failure in NBE:", oe);
            }
            finally
            {
                this.form.treeView1.EndUpdate();
            }
        }

        /// <summary>
        /// The reset tree.
        /// </summary>
        public void ResetTree()
        {
            if (this.form == null || !this.form.Created)
            {
                return;
            }

            try
            {
                this.form.treeView1.BeginUpdate();
                this.form.treeView1.Nodes.Clear();

                foreach (var isss in TrackedObjects)
                {
                    this.form.treeView1.Nodes.Add(
                        new ReflectionExplorableObject(isss, isss.GetType().Name + "/" + isss, null).Visualize());
                }
            }
            finally
            {
                this.form.treeView1.EndUpdate();
            }
        }

        /// <summary>
        /// The show form.
        /// </summary>
        public void ShowForm()
        {
          
                if (this.form == null || !this.form.Created)
                {
                    if (this.form != null)
                    {
                        try
                        {
                            this.form.Close();
                        }
                        catch
                        {
                        }

                        try
                        {
                            this.form.Dispose();
                        }
                        catch
                        {
                        }
                    }

                    this.form = new ObjectTreeViewerForm(this);
                }

                this.form.Show();
            
        }
    }
}